﻿using FlyingEye.HttpServices;
using FlyingEye.Views;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Windows;

namespace FlyingEye
{
    internal class WpfApp : System.Windows.Application
    {
        [STAThread]
        private static void Main()
        {
            WpfApp wpfApp = new WpfApp();
            wpfApp.Run();
        }

        public WpfApp()
        {
            this.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri("pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml")
            });
            this.Resources.MergedDictionaries.Add(new ResourceDictionary
            {
                Source = new Uri("pack://application:,,,/HandyControl;component/Themes/Theme.xaml")
            });
        }

        public const string AppId = "f7a9c1e2-4b8d-4e3f-a6c5-12d34e56f789";

        private static Mutex? InstanceMutex = null;

        private static bool AlreadyRun()
        {
            if (Mutex.TryOpenExisting(AppId, out var mutex))
            {
                return true;
            }

            InstanceMutex = new Mutex(true, AppId);

            return false;
        }

        /// <summary>
        /// 添加证书，会弹出一个添加证书窗口，取消操作，程序直接异常退出
        /// </summary>
        private static void EnsureLoadCert()
        {
            var baseDir = AppContext.BaseDirectory;

            // 打开受信任的根证书颁发机构存储  
            using (X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser))
            {
                // 打开存储区以进行写操作  
                store.Open(OpenFlags.ReadWrite);

                var existingCert = store.Certificates.FirstOrDefault(item => item.Issuer == "O=FlyingEye, L=NONE, S=NONE, C=CH");

                if (existingCert == null)
                {
                    var file = System.IO.Path.Combine(baseDir, "Assets/certificate.pfx");
                    var cert = new X509Certificate2(file, "1q2w3e*");

                    // 将证书添加到存储区  
                    store.Add(cert);
                }

                // 关闭存储区  
                store.Close();
            }
        }

        private string _resoutceId = string.Empty;

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            if (AlreadyRun())
            {
                MessageBox.Show("软件已运行！", "提示");
                this.Shutdown();
                return;
            }

            if (!HslCommunication.Authorization.SetAuthorizationCode("7525828d-68c9-4d31-b6db-e5162b91ef7b"))
            {
                MessageBox.Show("HSL 授权失败！", "提示");
                this.Shutdown();
                return;
            }

            var module = new FlyingEyeClientModule();
            _host = module.Build();

            this.DispatcherUnhandledException += (s, e) =>
            {
                _host.Services.GetRequiredService<ILogger<WpfApp>>()
                    .LogError(e.Exception, e.Exception.Message);
                MessageBox.Show(e.Exception.Message, "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);

                this.Dispatcher.Invoke(() =>
                {
                    Task.Run(() =>
                    {
                        _host.Services.GetRequiredService<ComeNotificationService>()
                    .PostMessage($"飞眼设备客户端 {_resoutceId} 发生了未处理的异常：{e.Exception.Message}").Wait();
                    });
                });

                e.Handled = true; // 处理异常
                // 关闭应用程序
                this.Shutdown();
            };

            AppDomain.CurrentDomain.UnhandledException += (s, e) =>
            {
                if (e.ExceptionObject is Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误提示", MessageBoxButton.OK, MessageBoxImage.Error);
                    _host.Services.GetRequiredService<ILogger<WpfApp>>()
                   .LogError(ex, "应用程序发生了未处理的异常！");

                    this.Dispatcher.Invoke(() =>
                    {
                        Task.Run(() =>
                        {
                            _host.Services.GetRequiredService<ComeNotificationService>()
                        .PostMessage($"飞眼设备客户端 {_resoutceId} 发生了未处理的异常：{ex.Message}").Wait();
                        });
                    });
                }
                this.Shutdown();
            };

            // 必须先确保加载证书
            EnsureLoadCert();

            var mainWindow = _host.Services.GetRequiredService<MainWindow>();
            _resoutceId = mainWindow.GetResourceId();

            this.MainWindow = mainWindow;
            mainWindow.Show();

            CloseStartLoadingAsync();

            var path = System.IO.Path.Combine(
                AppContext.BaseDirectory,
                Assembly.GetEntryAssembly()!.GetName().Name + ".exe");
            WindowsApi.SetAutoStart($"FlyingEyeClient[{AppId}]", path);

            _host.Services.GetRequiredService<ILogger<WpfApp>>()
                .LogInformation("应用程序启动成功！");
        }

        private Task CloseStartLoadingAsync()
        {
            return Task.Run(() =>
            {
                var asm = Assembly.GetEntryAssembly();
                var type = asm?.GetType("FlyingEye.LauncherLoading");
                var closeMethod = type?.GetMethod("Close", BindingFlags.Public | BindingFlags.Static);

                closeMethod?.Invoke(null, null);
            });
        }

        private IHost? _host { get; set; }
    }
}
